<!DOCTYPE html>
<html lang="zh-Hans">
<head>

    <!--[if lt IE 9]>
        <style>body {display: none; background: none !important} </style>
        <meta http-equiv="Refresh" Content="0; url=//outdatedbrowser.com/" />
    <![endif]-->

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="format-detection" content="telephone=no" />
<meta name="author" content="王诗翔" />



<meta name="description" content="来源： Linux命令行与shell脚本编程大全 内容   基本的脚本函数 返回值 在函数中使用变量 数组变量和函数 函数递归 创建库 在命令行上使用函数   我们可以将shell脚本代码放进函数中封装起来，这样就能在脚本中的任何地方多次使用它了。 下面我们来逐步了解如何创建自己的shell脚本函数并在应用中使用它们。">
<meta name="keywords" content="shell笔记,linux">
<meta property="og:type" content="article">
<meta property="og:title" content="创建和使用shell函数">
<meta property="og:url" content="https://shixiangwang.github.io/2017/11/26/shell-create-function/index.html">
<meta property="og:site_name" content="Cloudberry">
<meta property="og:description" content="来源： Linux命令行与shell脚本编程大全 内容   基本的脚本函数 返回值 在函数中使用变量 数组变量和函数 函数递归 创建库 在命令行上使用函数   我们可以将shell脚本代码放进函数中封装起来，这样就能在脚本中的任何地方多次使用它了。 下面我们来逐步了解如何创建自己的shell脚本函数并在应用中使用它们。">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2018-01-27T04:08:42.946Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="创建和使用shell函数">
<meta name="twitter:description" content="来源： Linux命令行与shell脚本编程大全 内容   基本的脚本函数 返回值 在函数中使用变量 数组变量和函数 函数递归 创建库 在命令行上使用函数   我们可以将shell脚本代码放进函数中封装起来，这样就能在脚本中的任何地方多次使用它了。 下面我们来逐步了解如何创建自己的shell脚本函数并在应用中使用它们。">

<link rel="apple-touch-icon" href= "/apple-touch-icon.png">


    <link rel="alternate" href="/atom.xml" title="Cloudberry" type="application/atom+xml">



    <link rel="shortcut icon" href="/favicon.png">



    <link href="//cdn.bootcss.com/animate.css/3.5.1/animate.min.css" rel="stylesheet">



    <link href="//cdn.bootcss.com/fancybox/2.1.5/jquery.fancybox.min.css" rel="stylesheet">



    <script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script>
    <link href="//cdn.bootcss.com/pace/1.0.2/themes/blue/pace-theme-minimal.css" rel="stylesheet">


<link rel="stylesheet" href="../../../../css/style.css">



<link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">


<title>创建和使用shell函数 | Cloudberry</title>

<script src="//cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>

<script>
    var yiliaConfig = {
        fancybox: true,
        animate: true,
        isHome: false,
        isPost: true,
        isArchive: false,
        isTag: false,
        isCategory: false,
        fancybox_js: "//cdn.bootcss.com/fancybox/2.1.5/jquery.fancybox.min.js",
        scrollreveal: "//cdn.bootcss.com/scrollReveal.js/3.1.4/scrollreveal.min.js",
        search: true
    }
</script>


    <script>
        yiliaConfig.jquery_ui = [true, "//cdn.bootcss.com/jqueryui/1.10.4/jquery-ui.min.js", "//cdn.bootcss.com/jqueryui/1.10.4/css/jquery-ui.min.css"];
    </script>



    <script> yiliaConfig.rootUrl = "\/";</script>






</head>
<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
    <header id="header" class="inner">
        <a href="/" class="profilepic">
            <img src="/img/avatar.png" class="animated zoomIn">
        </a>
        <hgroup>
          <h1 class="header-author"><a href="/">王诗翔</a></h1>
        </hgroup>

        
        <p class="header-subtitle">A site for writing life</p>
        

        
            <form id="search-form">
            <input type="text" id="local-search-input" name="q" placeholder="search..." class="search form-control" autocomplete="off" autocorrect="off" searchonload="false" />
            <i class="fa fa-times" onclick="resetSearch()"></i>
            </form>
            <div id="local-search-result"></div>
            <p class='no-result'>No results found <i class='fa fa-spinner fa-pulse'></i></p>
        


        
            <div id="switch-btn" class="switch-btn">
                <div class="icon">
                    <div class="icon-ctn">
                        <div class="icon-wrap icon-house" data-idx="0">
                            <div class="birdhouse"></div>
                            <div class="birdhouse_holes"></div>
                        </div>
                        <div class="icon-wrap icon-ribbon hide" data-idx="1">
                            <div class="ribbon"></div>
                        </div>
                        
                        <div class="icon-wrap icon-link hide" data-idx="2">
                            <div class="loopback_l"></div>
                            <div class="loopback_r"></div>
                        </div>
                        
                        
                        <div class="icon-wrap icon-me hide" data-idx="3">
                            <div class="user"></div>
                            <div class="shoulder"></div>
                        </div>
                        
                    </div>
                    
                </div>
                <div class="tips-box hide">
                    <div class="tips-arrow"></div>
                    <ul class="tips-inner">
                        <li>菜单</li>
                        <li>标签</li>
                        
                        <li>友情链接</li>
                        
                        
                        <li>关于我</li>
                        
                    </ul>
                </div>
            </div>
        

        <div id="switch-area" class="switch-area">
            <div class="switch-wrap">
                <section class="switch-part switch-part1">
                    <nav class="header-menu">
                        <ul>
                        
                            <li><a href="../../../../index.html">主页</a></li>
                        
                            <li><a href="../../../../archives/">所有文章</a></li>
                        
                            <li><a href="../../../../tags/">标签云</a></li>
                        
                            <li><a href="../../../../about/">关于我</a></li>
                        
                        </ul>
                    </nav>
                    <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fa Email" href="mailto:w_shixiang@163.com" title="Email"></a>
                            
                                <a class="fa GitHub" href="https://github.com/ShixiangWang" title="GitHub"></a>
                            
                                <a class="fa RSS" href="../../../../atom.xml" title="RSS"></a>
                            
                                <a class="fa 知乎" href="https://www.zhihu.com/people/wang-shi-xiang-65/activities" title="知乎"></a>
                            
                                <a class="fa 简书" href="https://www.jianshu.com/u/b6608e27dc74" title="简书"></a>
                            
                                <a class="fa Twitter" href="https://twitter.com/WangShxiang" title="Twitter"></a>
                            
                        </ul>
                    </nav>
                </section>
                
                
                <section class="switch-part switch-part2">
                    <div class="widget tagcloud" id="js-tagcloud">
                        <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/Gist/">Gist</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/Linux-shell/">Linux shell</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/OOP/">OOP</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/R/">R</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/Rmarkdown/">Rmarkdown</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/Rmd/">Rmd</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/Rstudio/">Rstudio</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/bash-shell/">bash shell</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/fasta/">fasta</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/git/">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/github/">github</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/lapply/">lapply</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/linux/">linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/markdown/">markdown</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/md/">md</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/python/">python</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/sapply/">sapply</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/sed/">sed</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/shell笔记/">shell笔记</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/survival/">survival</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/survminer/">survminer</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/vapply/">vapply</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/写作/">写作</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/数据处理/">数据处理</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/文本处理/">文本处理</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/生存分析/">生存分析</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/生物信息学/">生物信息学</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/类/">类</a></li><li class="tag-list-item"><a class="tag-list-link" href="../../../../tags/迭代计算/">迭代计算</a></li></ul>
                    </div>
                </section>
                
                
                
                <section class="switch-part switch-part3">
                    <div id="js-friends">
                    
                      <a class="main-nav-link switch-friends-link" href="http://www.ruanyifeng.com/blog/archives.html">阮一峰的网络日志</a>
                    
                      <a class="main-nav-link switch-friends-link" href="http://blog.fens.me/series-r/">R的极客理想系列</a>
                    
                      <a class="main-nav-link switch-friends-link" href="https://yihui.name/">谢益辉</a>
                    
                      <a class="main-nav-link switch-friends-link" href="http://www.huangshujia.me/">解螺旋的矿工</a>
                    
                      <a class="main-nav-link switch-friends-link" href="https://github.com/GuangchuangYu">GuangchuangYu</a>
                    
                      <a class="main-nav-link switch-friends-link" href="https://vip.biotrainee.com/">生信技能树</a>
                    
                    </div>
                </section>
                

                
                
                <section class="switch-part switch-part4">
                
                    <div id="js-aboutme">人该是自己生活的主宰，而不是别人手中的行货</div>
                </section>
                
            </div>
        </div>
    </header>                
</div>
    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
      <div class="overlay">
          <div class="slider-trigger"></div>
          <h1 class="header-author js-mobile-header hide"><a href="/" title="回到主页">王诗翔</a></h1>
      </div>
    <div class="intrude-less">
        <header id="header" class="inner">
            <a href="/" class="profilepic">
                <img src="/img/avatar.png" class="animated zoomIn">
            </a>
            <hgroup>
              <h1 class="header-author"><a href="/" title="回到主页">王诗翔</a></h1>
            </hgroup>
            
            <p class="header-subtitle">A site for writing life</p>
            
            <nav class="header-menu">
                <ul>
                
                    <li><a href="../../../../index.html">主页</a></li>
                
                    <li><a href="../../../../archives/">所有文章</a></li>
                
                    <li><a href="../../../../tags/">标签云</a></li>
                
                    <li><a href="../../../../about/">关于我</a></li>
                
                <div class="clearfix"></div>
                </ul>
            </nav>
            <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fa Email" target="_blank" href="mailto:w_shixiang@163.com" title="Email"></a>
                            
                                <a class="fa GitHub" target="_blank" href="https://github.com/ShixiangWang" title="GitHub"></a>
                            
                                <a class="fa RSS" target="_blank" href="../../../../atom.xml" title="RSS"></a>
                            
                                <a class="fa 知乎" target="_blank" href="https://www.zhihu.com/people/wang-shi-xiang-65/activities" title="知乎"></a>
                            
                                <a class="fa 简书" target="_blank" href="https://www.jianshu.com/u/b6608e27dc74" title="简书"></a>
                            
                                <a class="fa Twitter" target="_blank" href="https://twitter.com/WangShxiang" title="Twitter"></a>
                            
                        </ul>
            </nav>
        </header>                
    </div>
    <link class="menu-list" tags="标签" friends="友情链接" about="关于我"/>
</nav>
      <div class="body-wrap"><article id="post-shell-create-function" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="" class="article-date">
      <time datetime="2017-11-25T16:00:00.000Z" itemprop="datePublished">2017-11-26</time>
</a>


    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      创建和使用shell函数
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        
    <div class="article-category tagcloud">
    <a class="article-category-link" href="../../../../categories/Linux杂烩/">Linux杂烩</a><a class="article-category-link" href="../../../../categories/Linux杂烩/shell编程/">shell编程</a>
    </div>


        
    <div class="article-tag tagcloud">
        <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="../../../../tags/linux/">linux</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="../../../../tags/shell笔记/">shell笔记</a></li></ul>
    </div>

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
          
        <p><em>来源： Linux命令行与shell脚本编程大全</em></p>
<p><strong>内容</strong></p>
<blockquote>
<ul>
<li>基本的脚本函数</li>
<li>返回值</li>
<li>在函数中使用变量</li>
<li>数组变量和函数</li>
<li>函数递归</li>
<li>创建库</li>
<li>在命令行上使用函数</li>
</ul>
</blockquote>
<p>我们可以将shell脚本代码放进函数中封装起来，这样就能在脚本中的任何地方多次使用它了。</p>
<p>下面我们来逐步了解如何创建自己的shell脚本函数并在应用中使用它们。</p>
<a id="more"></a>
<h2 id="基本的脚本函数"><a href="#基本的脚本函数" class="headerlink" title="基本的脚本函数"></a>基本的脚本函数</h2><p>函数是一个脚本代码块，我们可以为其命名并在代码中任何位置重用。要在脚本中使用该代码块，只要使用所起的函数名就行了。</p>
<h3 id="创建函数"><a href="#创建函数" class="headerlink" title="创建函数"></a>创建函数</h3><p>有两种格式可以创建函数。第一种格式是使用关键字<code>function</code>，后跟分配给该代码块的函数名。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">funtion name&#123;</span><br><span class="line">truecommands</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>name</code>属性定义了赋予函数的唯一名称，<code>commands</code>是构成函数的一条或多条bash shell命令。</p>
<p>第二种格式更接近其他编程语言中定义函数的方式：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">name() &#123;</span><br><span class="line">  commands</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="使用函数"><a href="#使用函数" class="headerlink" title="使用函数"></a>使用函数</h3><p>要使用函数，只需要像其他shell命令一样，在行中指定函数名就行了。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test1</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using a <span class="keyword">function</span> <span class="keyword">in</span> a script</span></span><br><span class="line"></span><br><span class="line">function func1 &#123;</span><br><span class="line">    echo "This is an example of a function"</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">count=1</span><br><span class="line">while [ $count -le 5 ]</span><br><span class="line">do</span><br><span class="line">  func1</span><br><span class="line">  count=$[ $count + 1 ]</span><br><span class="line">done</span><br><span class="line"></span><br><span class="line">echo "This is the end of the loop"</span><br><span class="line">func1</span><br><span class="line">echo "Now, this is the end of the script"</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test1</span><br><span class="line">This is an example of a function</span><br><span class="line">This is an example of a function</span><br><span class="line">This is an example of a function</span><br><span class="line">This is an example of a function</span><br><span class="line">This is an example of a function</span><br><span class="line">This is the end of the loop</span><br><span class="line">This is an example of a function</span><br><span class="line">Now, this is the end of the script</span><br></pre></td></tr></table></figure>
<p>注意，定义函数名<code>func1</code>的后面一定要跟<code>{</code>有空格隔开，不然会报错。<strong>函数要先定义再使用，接触过编程的想必不陌生吧</strong>。</p>
<h2 id="返回值"><a href="#返回值" class="headerlink" title="返回值"></a>返回值</h2><p>bash shell会把函数当做一个小型脚本，运行结束时会返回一个退出状态码，有3种不同的方法来为函数生成退出状态码。</p>
<h3 id="默认退出状态码"><a href="#默认退出状态码" class="headerlink" title="默认退出状态码"></a>默认退出状态码</h3><p>默认函数的退出状态码是函数中最后一条命令返回的退出状态码。我们可以使用标准变量<code>$?</code>在函数执行结束后确定函数的状态码。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test2</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> testing the <span class="built_in">exit</span> status of a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">func1() &#123;</span><br><span class="line">trueecho "trying to display a non-existent file"</span><br><span class="line">truels -l badfile</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">echo "testing the function"</span><br><span class="line">func1</span><br><span class="line">echo "The exit status is: $?"</span><br><span class="line">wsx@wsx:~/tmp$ ./test2</span><br><span class="line">testing the function</span><br><span class="line">trying to display a non-existent file</span><br><span class="line">ls: 无法访问'badfile': 没有那个文件或目录</span><br><span class="line">The exit status is: 2</span><br></pre></td></tr></table></figure>
<p>函数的退出状态码是2，说明函数的最后一条命令没有成功运行。但你无法知道函数中其他命令中是否成功运行，我们来看看下面一个例子。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test3</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> testing the <span class="built_in">exit</span> status of a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">func1()&#123;</span><br><span class="line">truels -l badfile</span><br><span class="line">trueecho "This was a test of a bad command"</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">echo "testing the function:"</span><br><span class="line">func1</span><br><span class="line">echo "The exit status is: $?"</span><br><span class="line">wsx@wsx:~/tmp$ ./test3</span><br><span class="line">testing the function:</span><br><span class="line">ls: 无法访问'badfile': 没有那个文件或目录</span><br><span class="line">This was a test of a bad command</span><br><span class="line">The exit status is: 0</span><br></pre></td></tr></table></figure>
<p>这次函数的退出状态码是0，尽管其中有一条命令没有正常运行。可见使用函数的默认退出状态码是很危险的，幸运的是，我们有几种办法解决它。</p>
<h3 id="使用return命令"><a href="#使用return命令" class="headerlink" title="使用return命令"></a>使用return命令</h3><p><code>return</code>命令允许指定一个<strong>整数值</strong>来定义函数的退出状态码，从而提供了一种简单的途径来编码设定函数退出状态码。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test4</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using the <span class="built_in">return</span> <span class="built_in">command</span> <span class="keyword">in</span> a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">function db1 &#123;</span><br><span class="line">trueread -p "Enter a value: " value</span><br><span class="line">trueecho "doubling the value"</span><br><span class="line">truereturn $[ $value * 2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">db1</span><br><span class="line">echo "The new value is $?"</span><br><span class="line">wsx@wsx:~/tmp$ ./test4</span><br><span class="line">Enter a value: 4</span><br><span class="line">doubling the value</span><br><span class="line">The new value is 8</span><br></pre></td></tr></table></figure>
<p>当使用这种方法时要小心，记住下面两条技巧来避免问题：</p>
<ul>
<li>函数一结束就取返回值</li>
<li>退出状态码必须是0~255</li>
</ul>
<p>如果在用<code>$?</code>变量提取函数的返回值之前使用了其他命令，函数的返回值就会丢失。任何大于255的整数值都会产生一个错误值。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ ./test4</span><br><span class="line">Enter a value: 200</span><br><span class="line">doubling the value</span><br><span class="line">The new value is 144</span><br></pre></td></tr></table></figure>
<h3 id="使用函数输出"><a href="#使用函数输出" class="headerlink" title="使用函数输出"></a>使用函数输出</h3><p>如同可以将命令的输出保存到shell变量一样，我们也可以对函数的输出采用同样的处理办法。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">result=`db1`</span><br></pre></td></tr></table></figure>
<p>这个命令会将<code>db1</code>函数的输出赋值给<code>$result</code>变量。下面是脚本的一个实例：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test4b</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using the <span class="built_in">echo</span> to <span class="built_in">return</span> a value</span></span><br><span class="line"></span><br><span class="line">function db1 &#123;</span><br><span class="line">trueread -p "Enter a value: " value</span><br><span class="line">trueecho $[ $value * 2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">result=$(db1)</span><br><span class="line">echo "The new value is $result"</span><br><span class="line">wsx@wsx:~/tmp$ ./test4b</span><br><span class="line">Enter a value: 200</span><br><span class="line">The new value is 400</span><br></pre></td></tr></table></figure>
<p>函数会用<code>echo</code>语句来显示计算的结果，该脚本会查看<code>db1</code>函数的输出，而不是查看退出状态码。</p>
<blockquote>
<p>通过这种技术，我们还可以返回浮点值和字符串值，这使它成为一种获取函数返回值的强大方法。</p>
</blockquote>
<h2 id="在函数中使用变量"><a href="#在函数中使用变量" class="headerlink" title="在函数中使用变量"></a>在函数中使用变量</h2><p>在函数中使用变量时，我们需要注意它们的定义方式以及处理方法。这是shell脚本常见错误的根源。</p>
<h3 id="向函数传递参数"><a href="#向函数传递参数" class="headerlink" title="向函数传递参数"></a>向函数传递参数</h3><p>函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如，函数名会在<code>$0</code>变量中定义，函数命令行上的任何参数都会通过<code>$1</code>、<code>$2</code>定义。也可以用特殊变量<code>$#</code>来判断给函数的参数数目。</p>
<p>指定函数时，必须将参数和函数放在同一行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">func1 $value1 10</span><br></pre></td></tr></table></figure>
<p>然后函数可以用参数环境变量来获得参数值。下面是一个例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test5</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> passing parameters to a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">function addem &#123;</span><br><span class="line">trueif [ $# -eq 0 ] || [ $# -gt 2 ]</span><br><span class="line">truethen</span><br><span class="line">truetrueecho -1</span><br><span class="line">trueelif [ $# -eq 1 ]</span><br><span class="line">truethen</span><br><span class="line">truetrueecho $[ $1 + $1 ]</span><br><span class="line">trueelse</span><br><span class="line">truetrueecho $[ $1 + $2 ]</span><br><span class="line">truefi</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">echo -n "Adding 10 and 15: "</span><br><span class="line">value=$(addem 10 15)</span><br><span class="line">echo $value</span><br><span class="line">echo -n "Let's try adding just one number: "</span><br><span class="line">value=$(addem 10)</span><br><span class="line">echo $value</span><br><span class="line">echo -n "Now trying adding no numbers: "</span><br><span class="line">value=$(addem)</span><br><span class="line">echo $value</span><br><span class="line">echo -n "Finally, try add three numbers: "</span><br><span class="line">value=$(addem 10 15 20)</span><br><span class="line">echo $value</span><br><span class="line">wsx@wsx:~/tmp$ ./test5</span><br><span class="line">Adding 10 and 15: 25</span><br><span class="line">Let's try adding just one number: 20</span><br><span class="line">Now trying adding no numbers: -1</span><br><span class="line">Finally, try add three numbers: -1</span><br></pre></td></tr></table></figure>
<p><code>addem</code>函数首先会检查脚本传给它的参数数目。如果没有任何参数，或者参数多于两个，<code>addem</code>会返回<code>-1</code>。如果只有一个参数，<code>addem</code>会将参数与自身相加。如果有两个参数，<code>addem</code>会将它们相加。</p>
<p><strong>由于函数使用特殊参数环境变量作为自己的参数值，因此它无法直接获取脚本在命令行中的参数值。</strong>下面是个失败的例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat badtest1</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> trying to access script parameters inside a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">function badfunc1 &#123;</span><br><span class="line">trueecho $[ $1 * $2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">if [ $# -eq 2 ]</span><br><span class="line">then</span><br><span class="line">truevalue=$(badfunc1)</span><br><span class="line">trueecho "The result is $value"</span><br><span class="line">else</span><br><span class="line">trueecho "Usage: badtest1 a b"</span><br><span class="line">fi</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./badtest1 10 15</span><br><span class="line">./badtest1: 行 5: *  : 语法错误: 需要操作数 (错误符号是 "*  ")</span><br><span class="line">The result is</span><br></pre></td></tr></table></figure>
<p>尽管函数也使用了<code>$1</code>与<code>$2</code>变量，但它们与主脚本中的变量不同，要使用它们必须在调用函数时手动传入。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test6</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> trying to access script parameters inside a <span class="keyword">function</span></span></span><br><span class="line"></span><br><span class="line">function func1 &#123;</span><br><span class="line">trueecho $[ $1 * $2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">if [ $# -eq 2 ]</span><br><span class="line">then</span><br><span class="line">truevalue=$(func1 $1 $2)</span><br><span class="line">trueecho "The result is $value"</span><br><span class="line">else</span><br><span class="line">trueecho "Usage: badtest1 a b"</span><br><span class="line">fi</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test6</span><br><span class="line">Usage: badtest1 a b</span><br><span class="line">wsx@wsx:~/tmp$ ./test6 10 15</span><br><span class="line">The result is 150</span><br></pre></td></tr></table></figure>
<h3 id="在函数中处理变量"><a href="#在函数中处理变量" class="headerlink" title="在函数中处理变量"></a>在函数中处理变量</h3><p><strong>作用域</strong>是变量可见的区域。对脚本的其他部分而言，函数定义的变量是隐藏的。这些概念其实是编程语言中通用的，想必学过一些其他编程的朋友早已有所理解了。</p>
<p>函数使用两种类型的变量：</p>
<ul>
<li>全局变量</li>
<li>局部变量</li>
</ul>
<h4 id="全局变量"><a href="#全局变量" class="headerlink" title="全局变量"></a>全局变量</h4><p><strong>全局变量</strong>是在shell脚本中任何地方都有效的变量，如果你在函数内定义了一个全局变量，也可以在脚本的主体部分读取它的值。</p>
<p>默认情况下，我们在脚本中定义的任何变量都是全局变量。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test7</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using a global variable to pass a value</span></span><br><span class="line"></span><br><span class="line">function db1 &#123;</span><br><span class="line">truevalue=$[ $value * 2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">read -p "Enter a value: " value</span><br><span class="line">db1</span><br><span class="line">echo "The new value is: $value"</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test7</span><br><span class="line">Enter a value: 10</span><br><span class="line">The new value is: 20</span><br></pre></td></tr></table></figure>
<p>无论变量在函数内外定义，在脚本中引用该变量都有效。这样其实非常危险，尤其是如果你想在不同的shell脚本中使用函数的话。它要求你清清楚楚地知道函数中具体使用了哪些变量，包括那些用来计算非返回值的变量。下面是一个如何搞砸的例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat badtest2</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> demonstrating a bad use of variable</span></span><br><span class="line"></span><br><span class="line">function func1 &#123;</span><br><span class="line">truetemp=$[ $value + 5 ]</span><br><span class="line">trueresult=$[ $temp * 2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">temp=4</span><br><span class="line">value=6</span><br><span class="line"></span><br><span class="line">func1</span><br><span class="line">echo "The result is $result"</span><br><span class="line">if [ $temp -gt $value ]</span><br><span class="line">then</span><br><span class="line">trueecho "temp is larger"</span><br><span class="line">else</span><br><span class="line">trueecho "temp is smaller"</span><br><span class="line">fi</span><br><span class="line">wsx@wsx:~/tmp$ ./badtest2</span><br><span class="line">The result is 22</span><br><span class="line">temp is larger</span><br></pre></td></tr></table></figure>
<p>由于函数中用到了<code>$temp</code>变量，它的值在脚本中使用时受到了影响，产生了意想不到的后果。后面我们会学习如何处理这样的问题。</p>
<h4 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h4><p>无需在函数中使用全局变量，函数内部使用的任何变量都可以被声明成局部变量。<strong>我们只需要在变量声明前加上local关键字就可以了</strong>。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">local temp</span><br></pre></td></tr></table></figure>
<p>也可以在变量赋值时使用local关键字：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">local temp=$[ $value + 5 ]</span><br></pre></td></tr></table></figure>
<p><code>local</code>关键字保证了变量只局限于该函数中。我们再回看刚才的例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test8</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> demonstrating the <span class="built_in">local</span> keyword</span></span><br><span class="line"></span><br><span class="line">function func1 &#123;</span><br><span class="line">truelocal temp=$[ $value + 5 ]</span><br><span class="line">trueresult=$[ $temp * 2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">temp=4</span><br><span class="line">value=6</span><br><span class="line"></span><br><span class="line">func1</span><br><span class="line">echo "The result is $result"</span><br><span class="line">if [ $temp -gt $value ]</span><br><span class="line">then</span><br><span class="line">trueecho "temp is larger"</span><br><span class="line">else</span><br><span class="line">trueecho "temp is smaller"</span><br><span class="line">fi</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test8</span><br><span class="line">The result is 22</span><br><span class="line">temp is smaller</span><br></pre></td></tr></table></figure>
<h2 id="数组变量和函数"><a href="#数组变量和函数" class="headerlink" title="数组变量和函数"></a>数组变量和函数</h2><p>在函数中使用数组变量值有点麻烦，还需要一些特殊考虑。下面我们使用一种方法来解决问题。</p>
<h3 id="向函数传数组参数"><a href="#向函数传数组参数" class="headerlink" title="向函数传数组参数"></a>向函数传数组参数</h3><p>这个方法有点不好理解，将数组变量当做单个参数传递的话不起作用，下面我们看一个bad例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat badtest3</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> trying to pass an array variable</span></span><br><span class="line"></span><br><span class="line">function testit &#123;</span><br><span class="line">trueecho "The parameters are: $@"</span><br><span class="line">truethisarray=$1</span><br><span class="line">trueecho "The received array is $&#123;thisarray[*]&#125;"</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">myarray=(1 2 3 4 5)</span><br><span class="line">echo "The original array is: $&#123;myarray[*]&#125;"</span><br><span class="line">testit $myarray</span><br><span class="line">wsx@wsx:~/tmp$ ./badtest3</span><br><span class="line">The original array is: 1 2 3 4 5</span><br><span class="line">The parameters are: 1</span><br><span class="line">The received array is 1</span><br></pre></td></tr></table></figure>
<p>可以看到，当我们将数组变量当做函数参数传递时，函数只会取数组变量的第一个值。</p>
<p>针对这个问题，我们的一个解决方案是将数组变量全部拆分为单个值，然后作为参数传入函数，在函数内部又重新对这些值进行组装。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test9</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> array variable to <span class="keyword">function</span> <span class="built_in">test</span></span></span><br><span class="line"></span><br><span class="line">function testit &#123;</span><br><span class="line">truelocal newarray</span><br><span class="line">truenewarray=(`echo "$@"`)</span><br><span class="line">trueecho "The new array value is: $&#123;newarray[*]&#125;"</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">myarray=(1 2 3 4 5)</span><br><span class="line">echo $&#123;myarray[*]&#125;</span><br><span class="line">testit $&#123;myarray[*]&#125;</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test9</span><br><span class="line">1 2 3 4 5</span><br><span class="line">The new array value is: 1 2 3 4 5</span><br></pre></td></tr></table></figure>
<h3 id="从函数中返回数组"><a href="#从函数中返回数组" class="headerlink" title="从函数中返回数组"></a>从函数中返回数组</h3><p>采用与上面类似的方法，函数用<code>echo</code>语句来按正确顺序输出单个数组值，然后脚本再将它们重新放进一个新的数组变量中。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test10</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> returning an array value</span></span><br><span class="line"></span><br><span class="line">function arraydblr &#123;</span><br><span class="line">truelocal origarray</span><br><span class="line">truelocal newarray</span><br><span class="line">truelocal elements</span><br><span class="line">truelocal i</span><br><span class="line">trueorigarray=($(echo "$@"))</span><br><span class="line">truenewarray=($(echo "$@"))</span><br><span class="line">trueelements=$[ $# - 1 ]</span><br><span class="line">truefor (( i = 0; i &lt;= $elements; i++ ))</span><br><span class="line">true&#123;</span><br><span class="line"><span class="meta">		newarray[$</span><span class="bash">i]=$[ <span class="variable">$&#123;origarray[$i]&#125;</span> * 2]</span></span><br><span class="line">true&#125;</span><br><span class="line">trueecho $&#123;newarray[*]&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">myarray=(1 2 3 4 5)</span><br><span class="line">echo "The orignal array is $&#123;myarray[*]&#125;"</span><br><span class="line">arg1=$(echo $&#123;myarray[*]&#125;)</span><br><span class="line">result=($(arraydblr $arg1))</span><br><span class="line">echo "The new array is: $&#123;result[*]&#125;"</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test10</span><br><span class="line">The orignal array is 1 2 3 4 5</span><br><span class="line">The new array is: 2 4 6 8 10</span><br></pre></td></tr></table></figure>
<p>该脚本用<code>$arg1</code>变量将数组值传给<code>arraydblr</code>函数。该函数将数组重组到新的数组变量中，生成输出数组变量的一个副本，然后对数据元素进行遍历，将每个元素值翻倍，并将结果存入函数中该数组变量的副本。</p>
<h2 id="函数递归"><a href="#函数递归" class="headerlink" title="函数递归"></a>函数递归</h2><p>局部函数变量的一个特征是<strong>自成体系</strong>。这个特性使得函数可以递归地调用，也就是函数可以调用自己来得到结果。<strong>通常递归函数都有一个最终可以迭代到的基准值。</strong></p>
<p>递归算法的经典例子是计算阶乘：一个数的阶乘是该数之前的所有数乘以该数的值。</p>
<p>比如5的阶乘：</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">5</span>! = <span class="number">1</span> * <span class="number">2</span> * <span class="number">3</span> * <span class="number">4</span> * <span class="number">5</span></span><br></pre></td></tr></table></figure>
<p>方程可以简化为通用形式：</p>
<figure class="highlight llvm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">x</span>! = <span class="keyword">x</span> * (<span class="keyword">x</span><span class="number">-1</span>)!</span><br></pre></td></tr></table></figure>
<p>这可以用简单的递归脚本表达为：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">function factorial &#123;</span><br><span class="line">  if [ $1 -eq 1 ]</span><br><span class="line">  then</span><br><span class="line">  	echo 1</span><br><span class="line">  else</span><br><span class="line">  	local temp=$[ $1 - 1 ]</span><br><span class="line">  	local result=`factorial $temp`</span><br><span class="line">  	echo $[ $result * $1 ]</span><br><span class="line">  fi</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>下面用它来进行计算：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test11</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using recursion</span></span><br><span class="line"></span><br><span class="line">function factorial &#123;</span><br><span class="line">trueif [ $1 -eq 1 ]</span><br><span class="line">truethen</span><br><span class="line">truetrueecho 1</span><br><span class="line">trueelse</span><br><span class="line">truetruelocal temp=$[ $1 - 1]</span><br><span class="line">truetruelocal result=`factorial $temp`</span><br><span class="line">truetrueecho $[ $result * $1 ]</span><br><span class="line">truefi</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">read -p "Enter value: " value</span><br><span class="line">result=$(factorial $value)</span><br><span class="line">echo "The factorial of $value is: $result"</span><br><span class="line"></span><br><span class="line">wsx@wsx:~/tmp$ ./test11</span><br><span class="line">Enter value: 5</span><br><span class="line">The factorial of 5 is: 120</span><br></pre></td></tr></table></figure>
<h2 id="创建库"><a href="#创建库" class="headerlink" title="创建库"></a>创建库</h2><p>如果你碰巧要在多个脚本中使用同一段代码呢？显然在每个脚本中都定义同样的函数太麻烦了，一种解决方法就是创建<strong>库文件</strong>，然后在脚本中引用它。</p>
<p><strong>第一步</strong>是创建一个包含脚本中所需函数的公用库文件。下面是一个叫做myfuncs的库文件，定义了3个简单的函数。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat myfuncs</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> my script <span class="built_in">functions</span></span></span><br><span class="line"></span><br><span class="line">function addem &#123;</span><br><span class="line">trueecho $[ $1 + $2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function multem &#123;</span><br><span class="line">trueecho $[ $1 * $2 ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function divem &#123;</span><br><span class="line">trueif [ $2 -ne 0 ]</span><br><span class="line">truethen</span><br><span class="line">truetrueecho $[ $1 / $2 ]</span><br><span class="line">trueelse</span><br><span class="line">truetrueecho -1</span><br><span class="line">truefi</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>下一步</strong>是在用到这些函数的脚本文件中包含myfuncs库文件。</p>
<p>这里有点复杂，主要问题出在shell函数的作用域上。如果我们尝试像普通脚本一样运行库文件，函数不会出现在脚本中。</p>
<p>使用函数库的<strong>关键</strong>在于<code>source</code>命令。<strong><code>source</code>命令会在当前shell上下文中执行命令，而不是创建一个新的shell。</strong>通过<code>source</code>命令就可以使用库中的函数了。</p>
<p><code>source</code>命令有一个<strong>快捷别名</strong>，称为<strong>点操作符</strong>。要在shell脚本中运行myfuncs库文件，只需要使用下面这行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">. ./myfuncs</span><br></pre></td></tr></table></figure>
<p>注意第一个点是点操作符，而第二个点指向当前目录（相对路径）。</p>
<p>下面这个例子假定myfuncs库文件与要使用它的脚本位于同一目录，不然需要使用相对应的路径进行访问。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test12</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> using <span class="built_in">functions</span> defined <span class="keyword">in</span> a library file</span></span><br><span class="line"></span><br><span class="line">. ./myfuncs</span><br><span class="line"></span><br><span class="line">value1=10</span><br><span class="line">value2=5</span><br><span class="line">result1=$(addem $value1 $value2)</span><br><span class="line">result2=$(multem $value1 $value2)</span><br><span class="line">result3=$(divem $value1 $value2)</span><br><span class="line">echo "The result of adding them is: $result1"</span><br><span class="line">echo "The result of multiplying them is: $result2"</span><br><span class="line">echo "The result of dividing them is: $result3"</span><br></pre></td></tr></table></figure>
<p>运行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ ./test12</span><br><span class="line">The result of adding them is: 15</span><br><span class="line">The result of multiplying them is: 50</span><br><span class="line">The result of dividing them is: 2</span><br></pre></td></tr></table></figure>
<h2 id="在命令行上使用函数"><a href="#在命令行上使用函数" class="headerlink" title="在命令行上使用函数"></a>在命令行上使用函数</h2><p>有时候有必要在命令行界面的提示符下直接使用这些函数。这是个灰常不错的功能，在shell中定义的函数可以在整个系统中使用它，无需担心脚本是不是在PATH环境变量中。</p>
<p><strong>重点在于让shell能够识别这些函数</strong>。以下有几种方法可以实现。</p>
<h3 id="在命令行上创建函数"><a href="#在命令行上创建函数" class="headerlink" title="在命令行上创建函数"></a>在命令行上创建函数</h3><p>shell会解释用户输入的命令，所以可以在命令行上直接定义一个函数。</p>
<p>有两种方法。</p>
<p><strong>一种是采用单行方式定义函数。</strong></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ function divem &#123; echo $[ $1 / $2 ]; &#125;</span><br><span class="line">wsx@wsx:~/tmp$ divem 100 5</span><br><span class="line">20</span><br></pre></td></tr></table></figure>
<p>当在命令行上定义函数时，你<strong>必须</strong>记得在每个命令后面加个分号，这样shell能识别命令的起始。</p>
<p><strong>另一种是采用多行方式来定义函数。</strong>在定义时bash shell会使用次提示符来提示输入更多命令。这种方法不必在命令末尾加分号，只要按回车键就可。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ function multem &#123;</span><br><span class="line"><span class="meta">&gt;</span><span class="bash"> <span class="built_in">echo</span> $[ <span class="variable">$1</span> * <span class="variable">$2</span> ]</span></span><br><span class="line"><span class="meta">&gt;</span><span class="bash"> &#125;</span></span><br><span class="line">wsx@wsx:~/tmp$ multem 2 5</span><br><span class="line">10</span><br></pre></td></tr></table></figure>
<p><strong>注意</strong>：在命令行上创建函数不要跟内建命令重名，函数会覆盖原来的命令。</p>
<h3 id="在-bashrc文件中定义函数"><a href="#在-bashrc文件中定义函数" class="headerlink" title="在.bashrc文件中定义函数"></a>在.bashrc文件中定义函数</h3><p>在bash shell每次启动时都会在主目录下查找<code>.bashrc</code>文件，不管是交互式shell还是shell中启动的新shell。所以我们可以将函数写入该文件，或者在脚本中写入命令读取函数文件。操作前面都讲过，不再赘述，<strong>只要把该文件当做脚本对待就可以了</strong>。理解这一点这部分就会了。</p>
<h2 id="实例"><a href="#实例" class="headerlink" title="实例"></a>实例</h2><p><strong>在开源的世界里，共享代码才是关键，而这一点同样适用于脚本函数。</strong>我们可以下载大量各式各样的函数然后用于自己的应用程序。</p>
<p>这一节介绍<strong>如何下载、安装和使用GNU shtool shell脚本函数库</strong>。shtool库提供了一些简单的shell脚本函数，可以用来完成日常的shell功能。</p>
<h3 id="下载和安装"><a href="#下载和安装" class="headerlink" title="下载和安装"></a>下载和安装</h3><p>shtool软件包下载地址：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz # China</span><br></pre></td></tr></table></figure>
<p>可以浏览器或者命令行下载：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ wget http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz</span><br><span class="line">--2017-11-24 00:34:32--  http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz</span><br><span class="line">正在解析主机 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)... 202.141.176.110, 218.104.71.170, 2001:da8:d800:95::110</span><br><span class="line">正在连接 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)|202.141.176.110|:80... 已连接。</span><br><span class="line">已发出 HTTP 请求，正在等待回应... 200 OK</span><br><span class="line">长度： 97033 (95K) [application/gzip]</span><br><span class="line">正在保存至: “shtool-2.0.8.tar.gz”</span><br><span class="line"></span><br><span class="line">shtool-2.0.8.tar.gz 100%[===================&gt;]  94.76K  --.-KB/s    用时 0.1s</span><br><span class="line"></span><br><span class="line">2017-11-24 00:34:32 (783 KB/s) - 已保存 “shtool-2.0.8.tar.gz” [97033/97033])</span><br></pre></td></tr></table></figure>
<p>复制到主目录，然后用<code>tar</code>命令提取文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~$ tar -zxvf shtool-2.0.8.tar.gz</span><br><span class="line">shtool-2.0.8/AUTHORS</span><br><span class="line">shtool-2.0.8/COPYING</span><br><span class="line">shtool-2.0.8/ChangeLog</span><br><span class="line">shtool-2.0.8/INSTALL</span><br><span class="line">shtool-2.0.8/Makefile.in</span><br><span class="line">shtool-2.0.8/NEWS</span><br><span class="line">shtool-2.0.8/RATIONAL</span><br><span class="line">shtool-2.0.8/README</span><br><span class="line">shtool-2.0.8/THANKS</span><br><span class="line">shtool-2.0.8/VERSION</span><br><span class="line">shtool-2.0.8/configure</span><br><span class="line">shtool-2.0.8/configure.ac</span><br><span class="line">shtool-2.0.8/sh.arx</span><br><span class="line">shtool-2.0.8/sh.common</span><br><span class="line">shtool-2.0.8/sh.echo</span><br><span class="line">shtool-2.0.8/sh.fixperm</span><br><span class="line">shtool-2.0.8/sh.install</span><br><span class="line">shtool-2.0.8/sh.mdate</span><br><span class="line">shtool-2.0.8/sh.mkdir</span><br><span class="line">shtool-2.0.8/sh.mkln</span><br><span class="line">shtool-2.0.8/sh.mkshadow</span><br><span class="line">shtool-2.0.8/sh.move</span><br><span class="line">shtool-2.0.8/sh.path</span><br><span class="line">shtool-2.0.8/sh.platform</span><br><span class="line">shtool-2.0.8/sh.prop</span><br><span class="line">shtool-2.0.8/sh.rotate</span><br><span class="line">shtool-2.0.8/sh.scpp</span><br><span class="line">shtool-2.0.8/sh.slo</span><br><span class="line">shtool-2.0.8/sh.subst</span><br><span class="line">shtool-2.0.8/sh.table</span><br><span class="line">shtool-2.0.8/sh.tarball</span><br><span class="line">shtool-2.0.8/sh.version</span><br><span class="line">shtool-2.0.8/shtool.m4</span><br><span class="line">shtool-2.0.8/shtool.pod</span><br><span class="line">shtool-2.0.8/shtool.spec</span><br><span class="line">shtool-2.0.8/shtoolize.in</span><br><span class="line">shtool-2.0.8/shtoolize.pod</span><br><span class="line">shtool-2.0.8/test.db</span><br><span class="line">shtool-2.0.8/test.sh</span><br></pre></td></tr></table></figure>
<p>接下来可以构建shell脚本库文件了。</p>
<h3 id="构建库"><a href="#构建库" class="headerlink" title="构建库"></a>构建库</h3><p>shtool文件必须针对特定的Linux环境进行配置。<strong>配置工作必须使用标准的configure和make命令</strong>：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~$ cd shtool-2.0.8/</span><br><span class="line">wsx@wsx:~/shtool-2.0.8$ ./configure</span><br><span class="line">Configuring GNU shtool (Portable Shell Tool), version 2.0.8 (18-Jul-2008)</span><br><span class="line">Copyright (c) 1994-2008 Ralf S. Engelschall &lt;rse@engelschall.com&gt;</span><br><span class="line">checking whether make sets $(MAKE)... yes</span><br><span class="line">checking for perl interpreter... /usr/bin/perl</span><br><span class="line">checking for pod2man conversion tool... /usr/bin/pod2man</span><br><span class="line">configure: creating ./config.status</span><br><span class="line">config.status: creating Makefile</span><br><span class="line">config.status: creating shtoolize</span><br><span class="line">config.status: executing adjustment commands</span><br><span class="line">wsx@wsx:~/shtool-2.0.8$ make</span><br><span class="line">building program shtool</span><br><span class="line">./shtoolize -o shtool all</span><br><span class="line">Use of assignment to $[ is deprecated at ./shtoolize line 60.</span><br><span class="line">Generating shtool...(echo 11808/12742 bytes)...(mdate 3695/4690 bytes)...(table 1818/2753 bytes)...(prop 1109/2038 bytes)...(move 2685/3614 bytes)...(install 4567/5495 bytes)...(mkdir 2904/3821 bytes)...(mkln 4429/5361 bytes)...(mkshadow 3260/4193 bytes)...(fixperm 1471/2403 bytes)...(rotate 13425/14331 bytes)...(tarball 5297/6214 bytes)...(subst 5255/6180 bytes)...(platform 21739/22662 bytes)...(arx 2401/3312 bytes)...(slo 4139/5066 bytes)...(scpp 6295/7206 bytes)...(version 10234/11160 bytes)...(path 4041/4952 bytes)</span><br><span class="line">building manpage shtoolize.1</span><br><span class="line">building manpage shtool.1</span><br><span class="line">building manpage shtool-echo.1</span><br><span class="line">building manpage shtool-mdate.1</span><br><span class="line">shtool-mdate.tmp around line 222: You forgot a '=back' before '=head1'</span><br><span class="line">POD document had syntax errors at /usr/bin/pod2man line 71.</span><br><span class="line">building manpage shtool-table.1</span><br><span class="line">building manpage shtool-prop.1</span><br><span class="line">building manpage shtool-move.1</span><br><span class="line">building manpage shtool-install.1</span><br><span class="line">building manpage shtool-mkdir.1</span><br><span class="line">shtool-mkdir.tmp around line 186: You forgot a '=back' before '=head1'</span><br><span class="line">POD document had syntax errors at /usr/bin/pod2man line 71.</span><br><span class="line">building manpage shtool-mkln.1</span><br><span class="line">building manpage shtool-mkshadow.1</span><br><span class="line">shtool-mkshadow.tmp around line 191: You forgot a '=back' before '=head1'</span><br><span class="line">POD document had syntax errors at /usr/bin/pod2man line 71.</span><br><span class="line">building manpage shtool-fixperm.1</span><br><span class="line">building manpage shtool-rotate.1</span><br><span class="line">building manpage shtool-tarball.1</span><br><span class="line">building manpage shtool-subst.1</span><br><span class="line">building manpage shtool-platform.1</span><br><span class="line">building manpage shtool-arx.1</span><br><span class="line">building manpage shtool-slo.1</span><br><span class="line">building manpage shtool-scpp.1</span><br><span class="line">building manpage shtool-version.1</span><br><span class="line">building manpage shtool-path.1</span><br></pre></td></tr></table></figure>
<p><code>configure</code>命令会检查构建shtool库文件所必需的软件。一旦发现所需工具，它会使用工具路径修改配置文件。</p>
<p><code>make</code>命令负责构建shtool库文件。最终的结果（shtool）是一个完整的库软件包。</p>
<p>我们可以测试下这个库文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/shtool-2.0.8$ make test</span><br><span class="line">Running test suite:</span><br><span class="line">echo..........FAILED</span><br><span class="line">+---Test------------------------------</span><br><span class="line">| test ".`../shtool echo foo bar quux`" = ".foo bar quux" || exit 1</span><br><span class="line">| bytes=`../shtool echo -n foo | wc -c | awk '&#123; printf("%s", $1); &#125;'` || exit 1</span><br><span class="line">| test ".$bytes" = .3 || exit 1</span><br><span class="line">| bytes=`../shtool echo '\1' | wc -c | awk '&#123; printf("%s", $1); &#125;'` || exit 1</span><br><span class="line">| test ".$bytes" = .3 || exit 1</span><br><span class="line">| exit 0</span><br><span class="line">+---Trace-----------------------------</span><br><span class="line">| + ../shtool echo foo bar quux</span><br><span class="line">| + test .foo bar quux = .foo bar quux</span><br><span class="line">| + ../shtool echo -n foo</span><br><span class="line">| + wc -c</span><br><span class="line">| + awk &#123; printf("%s", $1); &#125;</span><br><span class="line">| + bytes=3</span><br><span class="line">| + test .3 = .3</span><br><span class="line">| + ../shtool echo \1</span><br><span class="line">| + wc -c</span><br><span class="line">| + awk &#123; printf("%s", $1); &#125;</span><br><span class="line">| + bytes=2</span><br><span class="line">| + test .2 = .3</span><br><span class="line">| + exit 1</span><br><span class="line">+-------------------------------------</span><br><span class="line">mdate.........ok</span><br><span class="line">table.........ok</span><br><span class="line">prop..........ok</span><br><span class="line">move..........ok</span><br><span class="line">install.......ok</span><br><span class="line">mkdir.........ok</span><br><span class="line">mkln..........ok</span><br><span class="line">mkshadow......ok</span><br><span class="line">fixperm.......ok</span><br><span class="line">rotate........ok</span><br><span class="line">tarball.......ok</span><br><span class="line">subst.........ok</span><br><span class="line">platform......ok</span><br><span class="line">arx...........ok</span><br><span class="line">slo...........ok</span><br><span class="line">scpp..........ok</span><br><span class="line">version.......ok</span><br><span class="line">path..........ok</span><br><span class="line">FAILED: passed: 18/19, failed: 1/19</span><br></pre></td></tr></table></figure>
<p>（有一个没通过～）</p>
<p>如果全部通过测试，就可以将库安装到系统中，这样所有脚本都能使用这个库了。</p>
<p>要完成安装，需要使用<code>make</code>命令的<code>install</code>选项。需要使用root权限。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/shtool-2.0.8$ make install</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/bin</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/share/man/man1</span><br><span class="line">mkdir: cannot create directory '/usr/local/share/man/man1': Permission denied</span><br><span class="line">chmod: cannot access '/usr/local/share/man/man1': No such file or directory</span><br><span class="line">Makefile:94: recipe for target 'install' failed</span><br><span class="line">make: *** [install] Error 1</span><br><span class="line">wsx@wsx:~/shtool-2.0.8$ sudo make install</span><br><span class="line">[sudo] wsx 的密码：</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/bin</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/share/man/man1</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/share/aclocal</span><br><span class="line">./shtool mkdir -f -p -m 755 /usr/local/share/shtool</span><br><span class="line">./shtool install -c -m 755 shtool /usr/local/bin/shtool</span><br><span class="line">./shtool install -c -m 755 shtoolize /usr/local/bin/shtoolize</span><br><span class="line">./shtool install -c -m 644 shtoolize.1 /usr/local/share/man/man1/shtoolize.1</span><br><span class="line">./shtool install -c -m 644 shtool.1 /usr/local/share/man/man1/shtool.1</span><br><span class="line">./shtool install -c -m 644 shtool-echo.1 /usr/local/share/man/man1/shtool-echo.1</span><br><span class="line">./shtool install -c -m 644 shtool-mdate.1 /usr/local/share/man/man1/shtool-mdate.1</span><br><span class="line">./shtool install -c -m 644 shtool-table.1 /usr/local/share/man/man1/shtool-table.1</span><br><span class="line">./shtool install -c -m 644 shtool-prop.1 /usr/local/share/man/man1/shtool-prop.1</span><br><span class="line">./shtool install -c -m 644 shtool-move.1 /usr/local/share/man/man1/shtool-move.1</span><br><span class="line">./shtool install -c -m 644 shtool-install.1 /usr/local/share/man/man1/shtool-install.1</span><br><span class="line">./shtool install -c -m 644 shtool-mkdir.1 /usr/local/share/man/man1/shtool-mkdir.1</span><br><span class="line">./shtool install -c -m 644 shtool-mkln.1 /usr/local/share/man/man1/shtool-mkln.1</span><br><span class="line">./shtool install -c -m 644 shtool-mkshadow.1 /usr/local/share/man/man1/shtool-mkshadow.1</span><br><span class="line">./shtool install -c -m 644 shtool-fixperm.1 /usr/local/share/man/man1/shtool-fixperm.1</span><br><span class="line">./shtool install -c -m 644 shtool-rotate.1 /usr/local/share/man/man1/shtool-rotate.1</span><br><span class="line">./shtool install -c -m 644 shtool-tarball.1 /usr/local/share/man/man1/shtool-tarball.1</span><br><span class="line">./shtool install -c -m 644 shtool-subst.1 /usr/local/share/man/man1/shtool-subst.1</span><br><span class="line">./shtool install -c -m 644 shtool-platform.1 /usr/local/share/man/man1/shtool-platform.1</span><br><span class="line">./shtool install -c -m 644 shtool-arx.1 /usr/local/share/man/man1/shtool-arx.1</span><br><span class="line">./shtool install -c -m 644 shtool-slo.1 /usr/local/share/man/man1/shtool-slo.1</span><br><span class="line">./shtool install -c -m 644 shtool-scpp.1 /usr/local/share/man/man1/shtool-scpp.1</span><br><span class="line">./shtool install -c -m 644 shtool-version.1 /usr/local/share/man/man1/shtool-version.1</span><br><span class="line">./shtool install -c -m 644 shtool-path.1 /usr/local/share/man/man1/shtool-path.1</span><br><span class="line">./shtool install -c -m 644 shtool.m4 /usr/local/share/aclocal/shtool.m4</span><br><span class="line">./shtool install -c -m 644 sh.common /usr/local/share/shtool/sh.common</span><br><span class="line">./shtool install -c -m 644 sh.echo /usr/local/share/shtool/sh.echo</span><br><span class="line">./shtool install -c -m 644 sh.mdate /usr/local/share/shtool/sh.mdate</span><br><span class="line">./shtool install -c -m 644 sh.table /usr/local/share/shtool/sh.table</span><br><span class="line">./shtool install -c -m 644 sh.prop /usr/local/share/shtool/sh.prop</span><br><span class="line">./shtool install -c -m 644 sh.move /usr/local/share/shtool/sh.move</span><br><span class="line">./shtool install -c -m 644 sh.install /usr/local/share/shtool/sh.install</span><br><span class="line">./shtool install -c -m 644 sh.mkdir /usr/local/share/shtool/sh.mkdir</span><br><span class="line">./shtool install -c -m 644 sh.mkln /usr/local/share/shtool/sh.mkln</span><br><span class="line">./shtool install -c -m 644 sh.mkshadow /usr/local/share/shtool/sh.mkshadow</span><br><span class="line">./shtool install -c -m 644 sh.fixperm /usr/local/share/shtool/sh.fixperm</span><br><span class="line">./shtool install -c -m 644 sh.rotate /usr/local/share/shtool/sh.rotate</span><br><span class="line">./shtool install -c -m 644 sh.tarball /usr/local/share/shtool/sh.tarball</span><br><span class="line">./shtool install -c -m 644 sh.subst /usr/local/share/shtool/sh.subst</span><br><span class="line">./shtool install -c -m 644 sh.platform /usr/local/share/shtool/sh.platform</span><br><span class="line">./shtool install -c -m 644 sh.arx /usr/local/share/shtool/sh.arx</span><br><span class="line">./shtool install -c -m 644 sh.slo /usr/local/share/shtool/sh.slo</span><br><span class="line">./shtool install -c -m 644 sh.scpp /usr/local/share/shtool/sh.scpp</span><br><span class="line">./shtool install -c -m 644 sh.version /usr/local/share/shtool/sh.version</span><br><span class="line">./shtool install -c -m 644 sh.path /usr/local/share/shtool/sh.path</span><br></pre></td></tr></table></figure>
<p>现在我们能在自己的shell脚本中使用这些函数咯。</p>
<h3 id="shtool库函数"><a href="#shtool库函数" class="headerlink" title="shtool库函数"></a>shtool库函数</h3><table>
<thead>
<tr>
<th>函数</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>Arx</td>
<td>创建归档文件（包含一些扩展功能）</td>
</tr>
<tr>
<td>Echo</td>
<td>显示字符串，并提供了一些扩展构件</td>
</tr>
<tr>
<td>fixperm</td>
<td>改变目录树的文件权限</td>
</tr>
<tr>
<td>install</td>
<td>安装脚本或文件</td>
</tr>
<tr>
<td>mdate</td>
<td>显示文件或目录修改时间</td>
</tr>
<tr>
<td>mkdir</td>
<td>创建一个或更多目录</td>
</tr>
<tr>
<td>Mkln</td>
<td>使用相对路径创建链接</td>
</tr>
<tr>
<td>mkshadow</td>
<td>创建一棵阴影树</td>
</tr>
<tr>
<td>move</td>
<td>带有替换功能的文件移动</td>
</tr>
<tr>
<td>Path</td>
<td>处理程序路径</td>
</tr>
<tr>
<td>platform</td>
<td>显示平台标识</td>
</tr>
<tr>
<td>Prop</td>
<td>显示一个带有动画效果的进度条</td>
</tr>
<tr>
<td>rotate</td>
<td>转置日志文件</td>
</tr>
<tr>
<td>Scpp</td>
<td>共享的C预处理器</td>
</tr>
<tr>
<td>Slo</td>
<td>根据库的类别，分离链接器选项</td>
</tr>
<tr>
<td>Subst</td>
<td>使用sed的替换操作</td>
</tr>
<tr>
<td>Table</td>
<td>以表格的形式显示由字段分隔的数据</td>
</tr>
<tr>
<td>tarball</td>
<td>从文件和目录中创建tar文件</td>
</tr>
<tr>
<td>version</td>
<td>创建版本信息文件</td>
</tr>
</tbody>
</table>
<p>每个shtool函数都包含大量的选项和参数。下面是使用格式：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">shtool [option] [function [option] [args]]</span><br></pre></td></tr></table></figure>
<h3 id="使用库"><a href="#使用库" class="headerlink" title="使用库"></a>使用库</h3><p>我们能直接在命令行或者在自己构建的脚本中使用shtool的函数。</p>
<p>下面是在脚本中使用的简单例子：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ cat test13</span><br><span class="line"><span class="meta">#</span><span class="bash">!/bin/bash</span></span><br><span class="line">shtool platform</span><br><span class="line">wsx@wsx:~/tmp$ ./test13</span><br><span class="line">Ubuntu 17.10 (AMD64)</span><br></pre></td></tr></table></figure>
<p><code>platform</code>函数会返回Linux发行版以及系统使用的CPU硬件相关信息。</p>
<p><code>prop</code>函数可以使用<code>\</code>,<code>|</code>,<code>/</code>和<code>-</code>字符创建一个旋转的进度条。它可以告诉shell脚本用户目前正在处理一些后台处理工作。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wsx@wsx:~/tmp$ ls -al /usr/bin | shtool prop -p "waiting..."</span><br><span class="line">waiting...</span><br></pre></td></tr></table></figure>
<p>在脚本学习中涉及到诸多的符号，在运行时我们可能会感觉到顺利，但自己写的时候往往会用不太对，推荐阅读一下常用的一些符号区分，像小括号、中括号、花括号等等。觉的不懂的可以看看<a href="http://blog.csdn.net/yangtalent1206/article/details/12996797" target="_blank" rel="noopener">Linux<em>Bash脚本</em>单引号’双引号“”反引号`小括号()中括号[]大括号{}</a>以及相关的百度资料。</p>

      
    </div>
    
  </div>
  
    
    <div class="copyright">
        <p><span>本文标题:</span><a href="">创建和使用shell函数</a></p>
        <!-- modify author information
        <p><span>文章作者:</span><a href="/" title="回到主页">王诗翔</a></p>
        -->
        <p><span>文章作者:</span>王诗翔</p>
        <p><span>发布时间:</span>2017-11-26, 00:00:00</p>
        <p><span>最后更新:</span>2018-01-27, 12:08:42</p>
        <p>
            <span>原始链接:</span><a class="post-url" href="" title="创建和使用shell函数">https://shixiangwang.github.io/2017/11/26/shell-create-function/</a>
            <span class="copy-path" data-clipboard-text="原文: https://shixiangwang.github.io/2017/11/26/shell-create-function/　　作者: 王诗翔" title="点击复制文章链接"><i class="fa fa-clipboard"></i></span>
            <script> var clipboard = new Clipboard('.copy-path'); </script>
        </p>
        <p>
            <span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" title="CC BY-NC-SA 4.0 International" target = "_blank">"署名-非商用-相同方式共享 4.0"</a> 转载请保留原文链接及作者。
        </p>
    </div>



    <nav id="article-nav">
        
            <div id="article-nav-newer" class="article-nav-title">
                <a href="../../29/shell-create-text-menu-and-window/">
                    使用shell创建文本菜单和窗口部件
                </a>
            </div>
        
        
            <div id="article-nav-older" class="article-nav-title">
                <a href="../../../09/20/OOPinR/">
                    R-面向对象编程
                </a>
            </div>
        
    </nav>


  
</article>

    <div id="toc" class="toc-article">
        <strong class="toc-title">文章目录</strong>
        
            <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#基本的脚本函数"><span class="toc-number">1.</span> <span class="toc-text">基本的脚本函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#创建函数"><span class="toc-number">1.1.</span> <span class="toc-text">创建函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用函数"><span class="toc-number">1.2.</span> <span class="toc-text">使用函数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#返回值"><span class="toc-number">2.</span> <span class="toc-text">返回值</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#默认退出状态码"><span class="toc-number">2.1.</span> <span class="toc-text">默认退出状态码</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用return命令"><span class="toc-number">2.2.</span> <span class="toc-text">使用return命令</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用函数输出"><span class="toc-number">2.3.</span> <span class="toc-text">使用函数输出</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#在函数中使用变量"><span class="toc-number">3.</span> <span class="toc-text">在函数中使用变量</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#向函数传递参数"><span class="toc-number">3.1.</span> <span class="toc-text">向函数传递参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#在函数中处理变量"><span class="toc-number">3.2.</span> <span class="toc-text">在函数中处理变量</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#全局变量"><span class="toc-number">3.2.1.</span> <span class="toc-text">全局变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#局部变量"><span class="toc-number">3.2.2.</span> <span class="toc-text">局部变量</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#数组变量和函数"><span class="toc-number">4.</span> <span class="toc-text">数组变量和函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#向函数传数组参数"><span class="toc-number">4.1.</span> <span class="toc-text">向函数传数组参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#从函数中返回数组"><span class="toc-number">4.2.</span> <span class="toc-text">从函数中返回数组</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#函数递归"><span class="toc-number">5.</span> <span class="toc-text">函数递归</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#创建库"><span class="toc-number">6.</span> <span class="toc-text">创建库</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#在命令行上使用函数"><span class="toc-number">7.</span> <span class="toc-text">在命令行上使用函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#在命令行上创建函数"><span class="toc-number">7.1.</span> <span class="toc-text">在命令行上创建函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#在-bashrc文件中定义函数"><span class="toc-number">7.2.</span> <span class="toc-text">在.bashrc文件中定义函数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#实例"><span class="toc-number">8.</span> <span class="toc-text">实例</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#下载和安装"><span class="toc-number">8.1.</span> <span class="toc-text">下载和安装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#构建库"><span class="toc-number">8.2.</span> <span class="toc-text">构建库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#shtool库函数"><span class="toc-number">8.3.</span> <span class="toc-text">shtool库函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用库"><span class="toc-number">8.4.</span> <span class="toc-text">使用库</span></a></li></ol></li></ol>
        
    </div>
    <style>
        .left-col .switch-btn,
        .left-col .switch-area {
            display: none;
        }
        .toc-level-3 i,
        .toc-level-3 ol {
            display: none !important;
        }
    </style>

    <input type="button" id="tocButton" value="隐藏目录"  title="点击按钮隐藏或者显示文章目录">

    <script>
        yiliaConfig.toc = ["隐藏目录", "显示目录", !!"false"];
    </script>



    
<div class="share">
    
        <div class="bdsharebuttonbox">
            <a href="#" class="fa fa-twitter bds_twi" data-cmd="twi" title="分享到推特"></a>
            <a href="#" class="fa fa-weibo bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
            <a href="#" class="fa fa-qq bds_sqq" data-cmd="sqq" title="分享给 QQ 好友"></a>
            <a href="#" class="fa fa-files-o bds_copy" data-cmd="copy" title="复制网址"></a>
            <a href="#" class="fa fa fa-envelope-o bds_mail" data-cmd="mail" title="通过邮件分享"></a>
            <a href="#" class="fa fa-weixin bds_weixin" data-cmd="weixin" title="生成文章二维码"></a>
            <a href="#" class="fa fa-share-alt bds_more" data-cmd="more"></i></a>
        </div>
        <script>
            window._bd_share_config={
                "common":{"bdSnsKey":{},"bdText":"创建和使用shell函数　| Cloudberry　","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
        </script>
    

    
</div>







    
        <section id="comments">
    <style> aside.comment-bar { margin: auto 30px; }</style>
    <div id="disqus_thread"></div>
    <script>
        var disqus_config = function(){
            this.page.url = 'https://shixiangwang.github.io/2017/11/26/shell-create-function/';
            this.page.identifier = '2017/11/26/shell-create-function/';
        };
        var loadComment = function(){
            var d = document, s = d.createElement('script');
            s.src = '//Cloudberry.disqus.com/embed.js';
            s.setAttribute('data-timestamp', +new Date());
            (d.head || d.body).appendChild(s);
        }
    </script>
    
    <script> loadComment(); </script>

</section>


    




    <div class="scroll" id="post-nav-button">
        
            <a href="../../29/shell-create-text-menu-and-window/" title="上一篇: 使用shell创建文本菜单和窗口部件">
                <i class="fa fa-angle-left"></i>
            </a>
        

        <a title="文章列表"><i class="fa fa-bars"></i><i class="fa fa-times"></i></a>

        
            <a href="../../../09/20/OOPinR/" title="下一篇: R-面向对象编程">
                <i class="fa fa-angle-right"></i>
            </a>
        
    </div>

    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="../../../../2018/02/26/python-basics/">两天研习Python基础</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/02/12/how-to-create-an-independent-figpath/">为markdown博文创建独立图片路径</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/02/10/easy-sapply-apply-vapply/">简单理解lapply,sapply,vapply</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/02/07/how-to-do-group-survival-analysis/">怎么对连续变量分组并进行生存分析</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/02/06/how-to-write-rmd-documents-in-hexo-system/">怎么在hexo博客系统中用Rmarkdown写文章</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/01/31/sed-how-to-filter-rows-before-using-command/">sed如何在执行命令前过滤特定文本行</a></li><li class="post-list-item"><a class="post-list-link" href="../../../../2018/01/31/sync-deploy-tools/">Sync deploy 命令工具</a></li><li class="post-list-item"><a class="post-list-link" href="../../../12/25/sed-and-gawk/">初识sed与awk</a></li><li class="post-list-item"><a class="post-list-link" href="../../../12/08/Git-basic-operation/">学习git</a></li><li class="post-list-item"><a class="post-list-link" href="../../29/shell-create-text-menu-and-window/">使用shell创建文本菜单和窗口部件</a></li><li class="post-list-item"><a class="post-list-link" href="">创建和使用shell函数</a></li><li class="post-list-item"><a class="post-list-link" href="../../../09/20/OOPinR/">R-面向对象编程</a></li><li class="post-list-item"><a class="post-list-link" href="../../../09/15/Class-in-R/">R中的属性与类</a></li><li class="post-list-item"><a class="post-list-link" href="../../../09/04/control_shell/">控制脚本</a></li><li class="post-list-item"><a class="post-list-link" href="../../../09/03/Linux-data-analysis-tools/">Linux数据处理命令工具</a></li><li class="post-list-item"><a class="post-list-link" href="../../../08/21/shell-show-data/">Linux脚本编程——呈现数据</a></li><li class="post-list-item"><a class="post-list-link" href="../../../08/19/working-with-user-input/">Shell脚本之处理用户输入</a></li><li class="post-list-item"><a class="post-list-link" href="../../../08/11/structural-command-of-shell/">Linux结构化命令</a></li><li class="post-list-item"><a class="post-list-link" href="../../../08/11/basic-shell/">构建基本shell脚本</a></li></ul>




    <script>
        
    </script>
</div>
      <footer id="footer">
    <div class="outer">
        <div id="footer-info">
            <div class="footer-left">
                <i class="fa fa-copyright"></i> 
                2017-2018 王诗翔
            </div>
            <div class="footer-right">
                <a href="http://hexo.io/" target="_blank" title="快速、简洁且高效的博客框架">Hexo</a>  Theme <a href="https://github.com/MOxFIVE/hexo-theme-yelee" target="_blank" title="简而不减 Hexo 双栏博客主题  v3.5">Yelee</a> by MOxFIVE <i class="fa fa-heart animated infinite pulse"></i>
            </div>
        </div>
        
            <div class="visit">
                
                    <span id="busuanzi_container_site_pv" style='display:none'>
                        <span id="site-visit" title="本站到访数"><i class="fa fa-user" aria-hidden="true"></i><span id="busuanzi_value_site_uv"></span>
                        </span>
                    </span>
                
                
                    <span>| </span>
                
                
                    <span id="busuanzi_container_page_pv" style='display:none'>
                        <span id="page-visit"  title="本页阅读量"><i class="fa fa-eye animated infinite pulse" aria-hidden="true"></i><span id="busuanzi_value_page_pv"></span>
                        </span>
                    </span>
                
            </div>
        
    </div>
</footer>
    </div>
    
    <script src="../../../../js/GithubRepoWidget.js"></script>

<script data-main="/js/main.js" src="//cdn.bootcss.com/require.js/2.2.0/require.min.js"></script>

    <script>
        $(document).ready(function() {
            var iPad = window.navigator.userAgent.indexOf('iPad');
            if (iPad > -1 || $(".left-col").css("display") === "none") {
                var bgColorList = ["#9db3f4", "#414141", "#e5a859", "#f5dfc6", "#c084a0", "#847e72", "#cd8390", "#996731"];
                var bgColor = Math.ceil(Math.random() * (bgColorList.length - 1));
                $("body").css({"background-color": bgColorList[bgColor], "background-size": "cover"});
            }
            else {
                var backgroundnum = 2;
                var backgroundimg = "url(/background/bg-x.jpg)".replace(/x/gi, Math.ceil(Math.random() * backgroundnum));
                $("body").css({"background": backgroundimg, "background-attachment": "fixed", "background-size": "cover"});
            }
        })
    </script>





    <script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
        processEscapes: true,
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    }
});

MathJax.Hub.Queue(function() {
    var all = MathJax.Hub.getAllJax(), i;
    for(i=0; i < all.length; i += 1) {
        all[i].SourceElement().parentNode.className += ' has-jax';                 
    }       
});
</script>

<script src="//cdn.bootcss.com/mathjax/2.6.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


<div class="scroll" id="scroll">
    <a href="#" title="返回顶部"><i class="fa fa-arrow-up"></i></a>
    <a href="#comments" onclick="load$hide();" title="查看评论"><i class="fa fa-comments-o"></i></a>
    <a href="#footer" title="转到底部"><i class="fa fa-arrow-down"></i></a>
</div>
<script>
    // Open in New Window
    
        var oOpenInNew = {
             github: ".github-widget a", 
            
             post: ".article-entry a[href], .copyright a[href]", 
            
            
            
             archives: ".archive-article-title", 
             miniArchives: "a.post-list-link", 
            
             friends: "#js-friends a", 
             socail: ".social a" 
        }
        for (var x in oOpenInNew) {
            $(oOpenInNew[x]).attr("target", "_blank");
        }
    
</script>

    <script>
        var originTitle = document.title;
        var titleTime;
        document.addEventListener("visibilitychange", function() {
            if (document.hidden) {
                document.title = "(つェ⊂) 我藏好了哦~ " + originTitle;
                clearTimeout(titleTime);
            }
            else {
                document.title = "(*´∇｀*) 被你发现啦~ " + originTitle;
                titleTime = setTimeout(function() {
                    document.title = originTitle;
                }, 2000);
            }
        })
    </script>

<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
  </div>
</body>
</html>